#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, m, l, t, tot, ov[N], cnt;
double st[N], cur[N], mon[N], lim; // where c[i].v == lim
bool use[N];
struct Car {
    double pos, v, a;
} c[N];
vector<int> v[N];
bool check(int x, int y) {
    int l = 0, r = 0;
    while(l < v[x].size()) {
        while(r!=v[y].size() && v[x][l]>v[y][r]) ++r;
        if(v[x][l] != v[y][r]) return false;
        ++l;
    }
    return true;
}
int main () {
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);
    scanf("%d", &t);
    while(t--) {
        tot = 0, cnt = 0;
        memset(use, 0, sizeof use);
        scanf("%d%d%d%lf", &n, &m, &l, &lim);
        for(int i = 1;i <= n;++i) scanf("%lf%lf%lf", &c[i].pos, &c[i].v, &c[i].a);
        for(int i = 1;i <= m;++i) scanf("%lf", mon+i), v[i].clear();
        for(int i = 1;i <= n;++i) {//how many cars are illegal
            int p = lower_bound(mon+1, mon+m+1, c[i].pos)-mon, p2;
            if(c[i].pos > mon[m]) continue;
            if(c[i].a > 0) {
                if(c[i].v > lim) {
                    ++tot;
                    for(int j = p;j <= m;++j) v[j].push_back(i);
                    continue;
                }
                else {
                    double k = c[i].pos + (lim*lim-c[i].v*c[i].v)/2/c[i].a;
                    if(k < mon[m]) {
                        ++tot;
                        p2 = upper_bound(mon+1, mon+m+1, k)-mon;
                        for(int j = p2;j <= m;++j) v[j].push_back(i);
                    }
                }
            }
            else if(c[i].a < 0) {
                if(c[i].v < lim) continue;
                else {
                    double k = c[i].pos + (lim*lim-c[i].v*c[i].v)/2/c[i].a;
                    if(k > mon[p]) {
                        ++tot;
                        p2 = lower_bound(mon+1, mon+m+1, k)-mon-1;
                        for(int j = p;j <= p2;++j) v[j].push_back(i);
                    }
                }
            }
            else {
                if(c[i].v > lim) {
                    ++tot;
                    for(int j = p;j <= m;++j) v[j].push_back(i);
                }
            }
        }
        printf("%d ", tot);
        int abl = 0;
        for(int i = 1;i <= m;++i) {
            if(use[i]) continue;
            for(int j = i+1;j <= m;++j) {
                if(use[j]) continue;
                if(check(i, j)) {
                    use[i] = true;
                    ++abl;
                    break;
                }
                else if(check(j, i)) {
                    use[j] = true;
                    ++abl;
                }
            }
            if(i == m) break;
        }
        printf("%d\n", abl);
    }
    return 0;
}
